package mdm.com.web.shiro;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;

import mdm.com.sap.RfcManager;
import mdm.com.web.common.AjaxResponse;
import mdm.com.web.session.TokenSession;
import mdm.com.web.session.TokenSessionManager;
import mdm.com.web.session.TokenUtil;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.web.filter.AccessControlFilter;
import org.apache.shiro.web.util.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.util.StringUtils;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Locale;
import java.util.Map;

/**
 * web请求拦截器 1)校验是否受保护的页面是否有登录token; 2)初始化身份信息; 3)功能权限校验;
 */
public class AuthWebFilter extends AccessControlFilter {
    private final static Logger LOGGER = LoggerFactory.getLogger(AuthWebFilter.class);

    private static final String zh_CN = "zh_CN";
    private static final String zh_HK = "zh_HK";
    private static final String en    = "en";

//    @Autowired
//    private MessageSource messageSource;

//    
//    public void setMessageSource(MessageSource messageSource) {
//        this.messageSource = messageSource;
//    }

//    private String getMessage(String key) {
//        return messageSource.getMessage(key, new Object[] {}, LocaleContextHolder.getLocale());
//    }

    @Override
    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
            throws Exception {
        LOGGER.info("come into AuthWebFilter.isAccessAllowed(),mappedValue=" + mappedValue);
        return false;
    }

    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
        LOGGER.info("come into AuthWebFilter.onAccessDenied()");

        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String url = WebUtils.getRequestUri(httpRequest);
        LOGGER.info("this request url is>>" + url);

        Map<String, String> chains = Maps.newHashMap();
        LOGGER.info("filter>>>" + httpRequest.getRequestURI().substring(httpRequest.getContextPath().length()));

        chains.put("/swagger", "anon");
        chains.put("/webjars", "anon");
        chains.put("/v2", "anon");
        chains.put("/login/", "anon");
        chains.put("/test", "anon");
        chains.put("/app", "anon");
        for (String key : chains.keySet()) {
            if (url.contains(key)) {
                return true;
            }
        }
        LOGGER.info("===========1===========");
        Cookie[] cookies = httpRequest.getCookies();
        String lang = zh_CN;
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if ("locale".equals(cookie.getName())) {
                    lang = cookie.getValue();
                }
            }
        }
        if (en.equals(lang)) {
            LocaleContextHolder.setLocale(new Locale("en"));
        } else if (zh_HK.equals(lang)) {
            LocaleContextHolder.setLocale(new Locale("zh", "HK"));
        } else {
            LocaleContextHolder.setLocale(new Locale("zh", "CN"));
        }
        LOGGER.info("===========2===========");
        // 校验是否已经登录
        if (!checkLoginToken(httpRequest)) {
            writeResponseMsg(httpResponse, 120,"用户未登录");
            LOGGER.info("checkLoginToken(httpRequest)>>" + checkLoginToken(httpRequest));
            return false;
        }
        return true;
    }

    private void writeResponseMsg(HttpServletResponse httpResponse, int status, String msg) throws Exception {
        AjaxResponse ap = new AjaxResponse();
        ap.setMessage(msg);
        ap.setStatus(status);
        String rs = JSONObject.toJSONString(ap);
        httpResponse.setHeader("Cache-Control", "no-cache");
        httpResponse.setCharacterEncoding("UTF-8");
        httpResponse.setContentType("application/json; charset=utf-8");
        httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        httpResponse.getOutputStream().write(rs.getBytes("UTF-8"));
    }

    /**
     * 校验用户是否已经登录以及会话是否有效
     */
    private boolean checkLoginToken(HttpServletRequest httpRequest) throws Exception {
        String token = httpRequest.getParameter("token");
        System.out.println("=============="+token);
        if (StringUtils.isEmpty(token)) {
            token = httpRequest.getHeader("token");
        }
        if (StringUtils.isEmpty(token)) {
            Cookie[] cookies = httpRequest.getCookies();
            if (cookies == null) {
                return false;
            }
            for (Cookie cookie : cookies) {
                if ("token".equals(cookie.getName())) {
                    token = cookie.getValue();
                }
            }
        }

        LOGGER.info("token>>" + token);

        if (StringUtils.isEmpty(token)) {
            return false;
        } else {
            TokenSession ses = TokenSessionManager.getInstance().getDomainTokenSession(token);
            if (ses == null) {
                return false;
            } else {
                // 刷新会话
                ses.touch();
            }
        }
        return true;
    }

    /**
     * 校验用户是否有资源访问权限
     */
    private boolean checkAuthPermission(HttpServletRequest httpRequest) throws Exception {
        String uri = httpRequest.getRequestURI().substring(httpRequest.getContextPath().length());
        if (uri.substring(uri.lastIndexOf("/") + 1).matches("[0-9]*")) {
            uri = uri.substring(0, uri.lastIndexOf("/") + 1);
        }
        LOGGER.info("--------------uri:{}", uri);
        LOGGER.info("----------user:{}----isPermitted:{}", TokenUtil.getUsername(TokenUtil.getToken(httpRequest)),
                SecurityUtils.getSubject().isPermitted(uri));

        return SecurityUtils.getSubject().isPermitted(uri);
    }

}
